home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-10-05 | 9.7 KB | 380 lines | [TEXT/MMCC] |
- /*================================================================================
- MenuHandler.c
-
- ©1991-4 Greg Anderson
- greggor@apple.com
-
- Menu bar routines
- ================================================================================*/
- #include <Balloons.h>
- #include <string.h>
- #include <stdlib.h>
- #include <AppleEvents.h>
-
- #include "MenuHandler.h"
- #include "WindowHandler.h"
-
- #include "StringUtilities.h"
- #include "MenuTable.h"
- #include "AboutBox.h"
-
- /*
- // Prototypes for private functions:
- */
- void FixupMenu( MenuHandle menuHand, short menu, short item );
- short NextLargestMenuID( short menuID );
- short FindItemID( short itemID );
- short FindMenuInTable( short menu, short item );
- void ProcessRange( short itemID, short groupSize, menuProc theProc, short param );
- void SetEnable( MenuHandle menuHand, short item, short enableFlag );
- void SetEnableRange( short itemID, short groupSize, short enableFlag );
- void DisableRange( short itemID, short groupSize );
- void EnableRange( short itemID, short groupSize );
- void CallCheckItem( MenuHandle menuHand, short item, short flag );
- void UncheckRange( short itemID, short groupSize );
- void DoDA( short theItem );
-
- /*----------------------------------------------------------------------
- // SetupMenuBar
- //
- // Set up and display the menu bar
- ----------------------------------------------------------------------*/
- void SetupMenuBar(short startMenu, short endMenu)
- {
- MenuHandle menuHand;
- MenuHandle helpMenu;
- Handle menuResource;
- char menuTitle[256];
- short smallestMenuID = 0x7FFF;
- short numberOfMenus;
- short menuResourceID;
- ResType menuResourceType;
- Str255 menuResourceName;
- short menuID;
- short item;
- short option;
- OSErr err;
-
- /*
- // Load all of the menus.
- */
- for( menuResourceID=startMenu; menuResourceID <= endMenu; ++menuResourceID )
- {
- menuHand = GetMenu( menuResourceID );
- if( menuHand )
- {
- /*
- // Pull out the MENU ID of this menu. The menu ID
- // of a menu is DIFFERENT THAN its resource ID.
- // The menu ID is the value that will be passed back
- // to your application in the high word of the result
- // of the function MenuSelect.
- //
- // Using ResEdit 2.1, you can set the Menu ID of
- // a menu by selecting the "Edit Menu & MDEF ID"
- // command in the "MENU" menu.
- */
- menuID = (*menuHand)->menuID;
- /*
- // Remember the ID of the menu with the smallest
- // ID. This menu is assumed to be the Apple Menu.
- */
- if( menuID < smallestMenuID )
- smallestMenuID = menuID;
- /*
- // Insert the menu in the menu bar
- */
- InsertMenu( menuHand, 0 );
- }
- }
- /*
- // Insert desk accessories into the Apple menu.
- */
- AddResMenu( GetMHandle(smallestMenuID),'DRVR');
- /*
- // Draw the menu bar
- */
- DrawMenuBar();
- }
-
- /*----------------------------------------------------------------------
- // FindItemID
- //
- // Find 'itemID' within the menuTable & return the index it was
- // found at
- ----------------------------------------------------------------------*/
- short FindItemID( short itemID )
- {
- short i;
-
- for(i=0;menuTable[i].itemID;++i)
- {
- if( menuTable[i].itemID == itemID )
- return( i );
- }
- return( -1 );
- }
-
- /*----------------------------------------------------------------------
- // AddItemIDtoTable
- //
- // Add an itemID to the menutable
- ----------------------------------------------------------------------*/
- void AddItemIDtoTable( short itemID, short menu, short item )
- {
- short i;
-
- i = FindItemID( itemID );
- if( i != -1 )
- {
- menuTable[i].menu = menu;
- menuTable[i].item = item;
- }
- }
-
- /*----------------------------------------------------------------------
- // FindMenuInTable
- //
- // Find 'itemID' within the menuTable & return the index it was
- // found at
- ----------------------------------------------------------------------*/
- short FindMenuInTable( short menu, short item )
- {
- short i;
-
- for(i=0;menuTable[i].itemID;++i)
- {
- if( (menuTable[i].menu == menu) && (menuTable[i].item == item) )
- return( i );
- }
- return( -1 );
- }
-
- /*----------------------------------------------------------------------
- // ProcessRange
- //
- // Process a range of menu item ids
- ----------------------------------------------------------------------*/
- void ProcessRange( short itemID, short groupSize, menuProc theProc, short param )
- {
- MenuHandle menuHand;
- short firstID;
- short i;
- short j;
-
- firstID = itemID - (itemID % groupSize);
- for(j=firstID;j<firstID+groupSize;++j)
- {
- i = FindItemID(j);
- if( i > -1 )
- {
- menuHand = GetMHandle(menuTable[i].menu);
- if( menuHand != nil )
- (*theProc)(menuHand,menuTable[i].item,param);
- }
- }
- }
-
- /*----------------------------------------------------------------------
- // SetEnable
- //
- // Used by SetEnableRange
- ----------------------------------------------------------------------*/
- void SetEnable( MenuHandle menuHand, short item, short enableFlag )
- {
- if( enableFlag )
- EnableItem(menuHand,item);
- else
- DisableItem(menuHand,item);
- }
-
- /*----------------------------------------------------------------------
- // SetEnableRange
- //
- // Either enable or disable a range of menu items
- ----------------------------------------------------------------------*/
- void SetEnableRange( short itemID, short groupSize, short enableFlag )
- {
- ProcessRange( itemID, groupSize, SetEnable, enableFlag );
- }
-
- /*----------------------------------------------------------------------
- // DisableRange
- //
- // Disable a range of menu items
- ----------------------------------------------------------------------*/
- void DisableRange( short itemID, short groupSize )
- {
- SetEnableRange( itemID, groupSize, false );
- }
-
- /*----------------------------------------------------------------------
- // EnableRange
- //
- // Enable a range of menu items
- ----------------------------------------------------------------------*/
- void EnableRange( short itemID, short groupSize )
- {
- SetEnableRange( itemID, groupSize, true );
- }
-
- /*----------------------------------------------------------------------
- // CallCheckItem
- //
- // This routine is necessary because 'CheckItem' is an inline
- // function,and cannot be passed as a procedure pointer
- ----------------------------------------------------------------------*/
- void CallCheckItem( MenuHandle menuHand, short item, short flag )
- {
- CheckItem(menuHand,item,flag);
- }
-
- /*----------------------------------------------------------------------
- // UncheckRange
- //
- // Remove the check mark from any (& every) menu item in a given menu
- ----------------------------------------------------------------------*/
- void UncheckRange( short itemID, short groupSize )
- {
- ProcessRange( itemID, groupSize, CallCheckItem, false );
- }
-
- /*----------------------------------------------------------------------
- // CheckOneItem
- //
- // Place a check mark by one item in a menu; remove the checks from
- // all other items in the group
- ----------------------------------------------------------------------*/
- void CheckOneItem( short itemID, short groupSize )
- {
- UncheckRange( itemID, groupSize );
- ProcessRange( itemID, 1, CallCheckItem, true );
- }
-
- /*----------------------------------------------------------------------
- // SetupMenuItems
- //
- // Enable all menus that need enabling; disable all that need
- // disabling; put check marks by the menus that need check marks.
- ----------------------------------------------------------------------*/
- void SetupMenuItems()
- {
- OSErr err = noErr;
-
- /*
- // Enable the "Close Window" menu item if there is an open window
- */
- SetEnableRange(M_CLOSEFRONT, 1, (FrontWindow() != nil));
-
- /*
- // First, enable / disable all menus based
- // on which of the menu's enable requirement
- // flags match the menu enable flags in the
- // frontmost window.
- */
- Try
- {
- FrontWindowHandler()->SetupMenus();
- }
- Catch(err)
- {
- }
- }
-
- /*----------------------------------------------------------------------
- // ProcessMenuSelection
- //
- // Some Menu item selected; find out which one
- ----------------------------------------------------------------------*/
- void ProcessMenuSelection( long menuResult )
- {
- GrafPtr savePort;
- Str255 selectionName;
- char selStr[256];
- short theItem = menuResult & 0x0FFFF;
- short theMenu = menuResult / 0x10000;
- short i;
-
- if( menuResult )
- {
- GetPort( &savePort );
-
- /*
- // Find the index within the menu table of the item selected.
- */
- i = FindMenuInTable( theMenu, theItem );
-
- OSErr err = noErr;
- Boolean frontWindowDidIt = false;
-
- Try
- {
- /*
- // Give the front window a chance to process the menu command
- */
- frontWindowDidIt = FrontWindowHandler()->ProcessMenuSelection(menuTable[i].itemID);
- }
- Catch(err)
- {
- }
-
- if(frontWindowDidIt == false)
- {
- /*
- // The apple menu is a special case...
- */
- if( theMenu == appleMenu )
- {
- if(theItem == 1)
- ShowAboutBox();
- else
- DoDA(theItem);
- }
- else
- {
- /*
- // If the front window didn't handle the command, and
- // if there is an entry in the menu function table,
- // then call it
- */
- if(menuTable[i].fMenuFunction != nil)
- {
- (*(menuTable[i].fMenuFunction))((CWindowPtr)FrontWindow(),menuTable[i].itemID);
- }
- }
- }
- /*
- // The OS hilites menus for us, but we must explicitly
- // un-hilite the menu title after we have processed the
- // command
- */
- HiliteMenu(0);
- SetPort( savePort );
- }
- }
-
- /*----------------------------------------------------------------------
- // DoDA
- //
- // A Desk Accessory has been opened
- ----------------------------------------------------------------------*/
- void DoDA( short theItem )
- {
- Str255 DAname;
-
- GetItem( GetMHandle(appleMenu), theItem, DAname );
- OpenDeskAcc(DAname);
- }
-
- /*----------------------------------------------------------------------
- // CloseFrontWindow
- //
- // Close the frontmost window
- ----------------------------------------------------------------------*/
- OSErr CloseFrontWindow(CWindowPtr window, short item)
- {
- GetWindowHandler(FrontWindow())->CloseWindowByUser();
-
- return noErr;
- }
-